﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Unis.Framework.Core.Exceptions;
using Unis.Framework.Core.Utility;
using ConfigurationManager = System.Configuration.ConfigurationManager;

namespace Unis.Framework.Core.Log
{
    public class TraceEx
    {
        // Fields
        private static string _APP_TEMP_PATH = string.Empty;
        private static DateTime _LastWriteDate = DateTime.Now;
        private static string _LastWriteMessage;
        private static Dictionary<string, int> _LogFileIndex = new Dictionary<string, int>();
        private static readonly string APP_LOG_FILE_NAME = "AppLogFile";
        private static readonly string LOG_CFG_FLAG_NAME = "LogEnabled";
        private const int MAX_COLUMN_COUNT = 0x80;
        private static readonly string MUST_LOG_SWITCH_NAME_IPS = "RunInfoAllowListenerIps";
        public const int SINGLE_LOG_FILE_MAX_SIZE = 0x100000;

        // Methods
        static TraceEx()
        {
            string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            if (baseDirectory.LastIndexOf(@"\") < (baseDirectory.Length - 1))
            {
                baseDirectory = baseDirectory + @"\";
            }
            _APP_TEMP_PATH = baseDirectory + "Log";
        }

        public static void Assert(bool condition, string msg)
        {
            Assert(condition, msg, "");
        }

        public static void Assert(bool condition, string msg, string detailMsg)
        {
            SaveIf(condition, msg + detailMsg, APPMessageType.CodeRunInfo, null);
        }

        private static bool checkAllowWriteRunLog()
        {
            string str = ConfigurationManager.AppSettings[LOG_CFG_FLAG_NAME];
            bool flag = !string.IsNullOrEmpty(str) && (System.String.Compare(str, "True", System.StringComparison.OrdinalIgnoreCase) == 0);
            if (!flag)
            {
                string str2 = ConfigurationManager.AppSettings[MUST_LOG_SWITCH_NAME_IPS];
                if (!string.IsNullOrEmpty(str2))
                {
                    string requestIP = CommonHelper.GetRequestIp();
                    flag = Array.IndexOf<string>(str2.Split(new char[] { ',' }), requestIP) >= 0;
                }
            }
            return flag;
        }

        private static int getCurrentLogFileIndex()
        {
            string key = DateTime.Now.ToString("yyyy-MM-dd");
            if (_LogFileIndex.ContainsKey(key))
            {
                return _LogFileIndex[key];
            }
            return 0;
        }

        public static string GetErrorMessageByType(APPMessageType msgLevel)
        {
            switch (msgLevel)
            {
                case APPMessageType.SysErrInfo:
                    return "系统错误";

                case APPMessageType.SysDatabaseInfo:
                    return "数据库操作失败";

                case APPMessageType.SysFileInfo:
                    return "硬盘文件操作失败";

                case APPMessageType.CodeRunInfo:
                    return "代码执行轨迹";

                case APPMessageType.OtherSysInfo:
                    return "代码执行失败";
            }
            return "其它信息";
        }

        private static string getValidLogFileName(string fullName, ref int index)
        {
            string str = string.Empty + "-" + ((int)index).ToString() + "#.txt";
            string path = fullName + str;
            if (!File.Exists(path))
            {
                writeCurrentLogFileIndex(index);
                return path;
            }
            FileInfo info = new FileInfo(path);
            if (info.Length < 0x100000)
            {
                writeCurrentLogFileIndex(index);
                return path;
            }
            index++;
            return getValidLogFileName(fullName, ref index);
        }

        public static bool SaveIf(bool condition, string msgStr, APPMessageType msgLevel, string fullPath)
        {
            if (!condition)
            {
                if (string.IsNullOrEmpty(msgStr))
                {
                    return true;
                }
                if (msgStr.Length > 0x2000)
                {
                    msgStr = msgStr.Substring(0, 0x80) + " [[单行日志超长,部分字符已经被截取掉]]";
                }
                if (msgLevel == APPMessageType.DisplayToUser)
                {
                    return true;
                }
                if ((msgLevel == APPMessageType.CodeRunInfo) && !checkAllowWriteRunLog())
                {
                    return true;
                }
                if (string.Compare(msgStr, _LastWriteMessage, true) == 0)
                {
                    if (DateTime.Now.Subtract(_LastWriteDate).TotalSeconds < 1.0)
                    {
                        _LastWriteDate = DateTime.Now;
                        return true;
                    }
                }
                else
                {
                    _LastWriteMessage = msgStr;
                }
                _LastWriteDate = DateTime.Now;
                string str = fullPath;
                if (string.IsNullOrEmpty(str))
                {
                    string str2 = ConfigurationManager.AppSettings[APP_LOG_FILE_NAME];
                    if (string.IsNullOrEmpty(str2))
                    {
                        str2 = "APP.Run.Log";
                    }
                    string str3 = "(" + DateTime.Now.ToString("yyyy-MM-dd") + ")";
                    str = APP_TEMP_PATH;
                    if (!Directory.Exists(str))
                    {
                        Directory.CreateDirectory(str);
                    }
                    str = str + @"\" + str3 + str2;
                }
                int index = getCurrentLogFileIndex();
                str = getValidLogFileName(str, ref index);
                StreamWriter writer = null;
                try
                {
                    writer = new StreamWriter(str, true);
                    string str4 = GetErrorMessageByType(msgLevel) + "-->";
                    string requestIP = CommonHelper.GetRequestIp();
                    if (!string.IsNullOrEmpty(requestIP))
                    {
                        requestIP = "(" + requestIP + ")";
                    }
                    string str6 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:") + requestIP + str4 + msgStr;
                    writer.WriteLine(str6);
                }
                catch
                {
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Flush();
                        writer.Close();
                    }
                }
            }
            return true;
        }

        public static void Write(string msgStr)
        {
            Write(msgStr, APPMessageType.CodeRunInfo);
        }

        public static void Write(string msgStr, APPMessageType msgLevel)
        {
            WriteIf(false, msgStr, msgLevel);
        }

        private static void writeCurrentLogFileIndex(int index)
        {
            string key = DateTime.Now.ToString("yyyy-MM-dd");
            if (_LogFileIndex.ContainsKey(key))
            {
                _LogFileIndex[key] = index;
            }
            else
            {
                _LogFileIndex.Add(key, index);
            }
        }

        public static void WriteIf(bool condition, string msgStr)
        {
            WriteIf(condition, msgStr, APPMessageType.CodeRunInfo);
        }

        public static void WriteIf(bool condition, string msgStr, APPMessageType msgLevel)
        {
            SaveIf(condition, msgStr, msgLevel, null);
        }

        // Properties
        public static string APP_TEMP_PATH
        {
            get
            {
                return _APP_TEMP_PATH;
            }
            set
            {
                _APP_TEMP_PATH = value;
                if (!Directory.Exists(_APP_TEMP_PATH))
                {
                    Directory.CreateDirectory(_APP_TEMP_PATH);
                }
            }
        }
    }

}
